using System;
#if FX1_1
using IList_ServiceElement = System.Collections.IList;
using List_ServiceElement = System.Collections.ArrayList;
using IList_ServiceAttribute = System.Collections.IList;
using List_ServiceAttribute = System.Collections.ArrayList;
#else
using IList_ServiceElement = System.Collections.Generic.IList<InTheHand.Net.Bluetooth.ServiceElement>;
using List_ServiceElement = System.Collections.Generic.List<InTheHand.Net.Bluetooth.ServiceElement>;
using IList_ServiceAttribute = System.Collections.Generic.IList<InTheHand.Net.Bluetooth.ServiceAttribute>;
using List_ServiceAttribute = System.Collections.Generic.List<InTheHand.Net.Bluetooth.ServiceAttribute>;
#endif
using System.Text;
using NUnit.Framework;
using InTheHand.Net.Bluetooth;
using InTheHand.Net.Tests.Sdp2;
using InTheHand.Net.Bluetooth.AttributeIds;

namespace InTheHand.Net.Tests.Sdp2
{

    [TestFixture]
    public class SdpHelperTests
    {

        [Test]
        public void GetChannelElementNotExists()
        {
            ServiceRecord rcd = new ServiceRecord();
            ServiceElement element = ServiceRecordHelper.GetRfcommChannelElement(rcd);
            Assert.IsNull(element);
        }

        [Test]
        public void GetChannelByteNotExists()
        {
            ServiceRecord rcd = new ServiceRecord();
            int value = ServiceRecordHelper.GetRfcommChannelNumber(rcd);
            Assert.AreEqual(-1, value);
        }

        [Test]
        public void GetChannelElementOpp()
        {
            ServiceRecord rcd = ServiceRecord.CreateServiceRecordFromBytes(Data_CompleteThirdPartyRecords.PalmOsOpp);
            ServiceElement element = ServiceRecordHelper.GetRfcommChannelElement(rcd);
            Assert.IsNotNull(element);
            Assert.AreEqual(ElementType.UInt8, element.ElementType);
            Assert.AreEqual(Data_CompleteThirdPartyRecords.PalmOsOpp_RfcommChannelNumber, element.Value);
        }

        [Test]
        public void GetChannelByteOpp()
        {
            ServiceRecord rcd = ServiceRecord.CreateServiceRecordFromBytes(Data_CompleteThirdPartyRecords.PalmOsOpp);
            int value = ServiceRecordHelper.GetRfcommChannelNumber(rcd);
            Assert.AreNotEqual(-1, value);
            Assert.AreEqual(Data_CompleteThirdPartyRecords.PalmOsOpp_RfcommChannelNumber, (byte)value);
        }

        [Test]
        public void GetChannelElementSdpNone()
        {
            ServiceRecord rcd = ServiceRecord.CreateServiceRecordFromBytes(Data_CompleteThirdPartyRecords.XpB_0of2Sdp);
            ServiceElement element = ServiceRecordHelper.GetRfcommChannelElement(rcd);
            Assert.IsNull(element);
        }

        [Test]
        public void GetChannelByteSdpNone()
        {
            ServiceRecord rcd = ServiceRecord.CreateServiceRecordFromBytes(Data_CompleteThirdPartyRecords.XpB_0of2Sdp);
            int value = ServiceRecordHelper.GetRfcommChannelNumber(rcd);
            Assert.AreEqual(-1, value);
        }

        [Test]
        public void GetChannelBytePdlHasUuid32s()
        {
            ServiceRecord rcd = ServiceRecord.CreateServiceRecordFromBytes(Data_CompleteThirdPartyRecords.KingSt_d2r1);
            int value = ServiceRecordHelper.GetRfcommChannelNumber(rcd);
            Assert.AreEqual(2, value);
        }

        [Test]
        public void GetChannelBytePdlHasUuid128s()
        {
            ServiceRecord rcd = ServiceRecord.CreateServiceRecordFromBytes(Data_CompleteThirdPartyRecords.KingSt_d2r1_withPdlUuid128s);
            int value = ServiceRecordHelper.GetRfcommChannelNumber(rcd);
            Assert.AreEqual(2, value);
        }

        //------------------------
        public const string CrLf = "\r\n";
        public const string ExpectedRfcommDump
            = "AttrId: 0x0004 -- ProtocolDescriptorList" + CrLf
            + "ElementSequence" + CrLf
            + "    ElementSequence" + CrLf
            + "        Uuid16: 0x100 -- L2CapProtocol" + CrLf
            + "    ElementSequence" + CrLf
            + "        Uuid16: 0x3 -- RFCommProtocol" + CrLf
            + "        UInt8: 0x0" + CrLf
            + "( ( L2Cap ), ( Rfcomm, ChannelNumber=0 ) )" + CrLf
            ;
        public const string ExpectedGoepDump
            = "AttrId: 0x0004 -- ProtocolDescriptorList" + CrLf
            + "ElementSequence" + CrLf
            + "    ElementSequence" + CrLf
            + "        Uuid16: 0x100 -- L2CapProtocol" + CrLf
            + "    ElementSequence" + CrLf
            + "        Uuid16: 0x3 -- RFCommProtocol" + CrLf
            + "        UInt8: 0x0" + CrLf
            + "    ElementSequence" + CrLf
            + "        Uuid16: 0x8 -- ObexProtocol" + CrLf
            + "( ( L2Cap ), ( Rfcomm, ChannelNumber=0 ), ( Obex ) )" + CrLf
            ;
        
        [Test]
        public void CreateRfcomm()
        {
            ServiceElement element = ServiceRecordHelper.CreateRfcommProtocolDescriptorList();
            //
            List_ServiceAttribute attrs = new List_ServiceAttribute();
            attrs.Add(new ServiceAttribute(UniversalAttributeId.ProtocolDescriptorList, element));
            ServiceRecord record = new ServiceRecord(attrs);
            String dump = ServiceRecordUtilities.Dump(record);
            Assert.AreEqual(ExpectedRfcommDump, dump, "RFCOMM ProtoDL dump");
        }

        [Test]
        public void CreateGoep()
        {
            ServiceElement element = ServiceRecordHelper.CreateGoepProtocolDescriptorList();
            //
            List_ServiceAttribute attrs = new List_ServiceAttribute();
            attrs.Add(new ServiceAttribute(UniversalAttributeId.ProtocolDescriptorList, element));
            ServiceRecord record = new ServiceRecord(attrs);
            String dump = ServiceRecordUtilities.Dump(record);
            Assert.AreEqual(ExpectedGoepDump, dump, "GOEP ProtoDL dump");
        }

        [Test]
        public void PalmOsOppCompleteRecord()
        {
            ServiceRecord record = CreatePalmOsOppCompleteRecord();
            ServiceRecordHelper.SetRfcommChannelNumber(record, 1);
            byte[] buf = new byte[256];
            int length = new ServiceRecordCreator().CreateServiceRecord(record, buf);
            //ServiceRecordUtilities.Dump(Console.Out, record);
            Assert2.AreEqualBuffers(Data_CompleteThirdPartyRecords.PalmOsOpp_HackMadeFirstLengthOneByteField, buf, length);
        }

        public ServiceRecord CreatePalmOsOppCompleteRecord()
        {
            List_ServiceAttribute attrs = new List_ServiceAttribute();
            ServiceElement element;
            List_ServiceElement list; 
            //
            attrs.Add(new ServiceAttribute(UniversalAttributeId.ServiceRecordHandle,
                new ServiceElement(ElementType.UInt32, (UInt32)0x10001)));
            //
            element = new ServiceElement(ElementType.Uuid16, (UInt16)0x1105);
            list = new List_ServiceElement();
            list.Add(element);
            element = new ServiceElement(ElementType.ElementSequence, list);
            attrs.Add(new ServiceAttribute(UniversalAttributeId.ServiceClassIdList, element));
            //
            element = ServiceRecordHelper.CreateGoepProtocolDescriptorList();
            attrs.Add(new ServiceAttribute(UniversalAttributeId.ProtocolDescriptorList, element));
            //
            const UInt16 Windows1252EncodingId = 2252;
            LanguageBaseItem[] languages = {
                new LanguageBaseItem("en", Windows1252EncodingId, LanguageBaseItem.PrimaryLanguageBaseAttributeId)
            };
            element = LanguageBaseItem.CreateElementSequenceFromList(languages);
            attrs.Add(new ServiceAttribute(UniversalAttributeId.LanguageBaseAttributeIdList, element));
            //
            // PalmOs really uses Windows-1252, but since the string is ASCII, UTF-8 is equivalent.
            element = new ServiceElement(ElementType.TextString, "OBEX Object Push");
            attrs.Add(new ServiceAttribute(
                ServiceRecord.CreateLanguageBasedAttributeId(UniversalAttributeId.ServiceName, 
                                            LanguageBaseItem.PrimaryLanguageBaseAttributeId),
                element));
            //
            list = new List_ServiceElement();
            list.Add(new ServiceElement(ElementType.UInt8, (byte)0x1));
            list.Add(new ServiceElement(ElementType.UInt8, (byte)0x2));
            list.Add(new ServiceElement(ElementType.UInt8, (byte)0x3));
            list.Add(new ServiceElement(ElementType.UInt8, (byte)0xFF));
            element = new ServiceElement(ElementType.ElementSequence, list);
            attrs.Add(new ServiceAttribute(ObexAttributeId.SupportedFormatsList, element));
            //
            ServiceRecord record = new ServiceRecord(attrs);
            return record;
        }


    }//class

}
